﻿using MQTTnet.Formatter;
using MQTTnet.Protocol;
using MQTTNet.Client.Enums;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace MQTTNet.Client
{
    public interface IMQTTNetClient:IDisposable
    {
        /// <summary>
        /// 连接回调
        /// </summary>
        Action<string> OnConnectionHandle { get; set; }
        /// <summary>
        /// 消息回调
        /// </summary>
        Action<string, string> OnMessageHandle { get; set; }
        /// <summary>
        /// 断开连接回调
        /// </summary>
        Action<string> OnDisConnectionHandle { get; set; }
        /// <summary>
        /// 错误回调
        /// </summary>
        public Action<string,string,Exception> OnErrorHandle { get; set; }
        /// <summary>
        /// 连接Id
        /// </summary>
        string? ClientId { get; }
        /// <summary>
        /// 连接状态
        /// </summary>
        bool IsConnected { get; }
        /// <summary>
        /// 初始化连接
        /// </summary>
        /// <param name="uri">服务器地址</param>
        /// <param name="port">服务器端口</param>
        /// <param name="UserName">用户名</param>
        /// <param name="Password">密码</param>
        /// <param name="clientId">自定义连接Id</param>
        /// <param name="MQTTVersion">MQTT版本默认 3.1.1</param>
        void InitMQTTClient(string uri, int port = 1883, string UserName = "", string Password = "", string clientId = "", MQTTVersionEnum MQTTVersion = MQTTVersionEnum.V311);
        /// <summary>
        /// 开始连接
        /// </summary>
        /// <param name="action">回调函数</param>
        /// <returns></returns>
        Task<bool> Connection(Action<IMQTTNetClient>? action=null);
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <returns></returns>
        Task<bool> DisConnection();
        /// <summary>
        /// 发布字符串消息
        /// </summary>
        /// <param name="topic">发布主题</param>
        /// <param name="message">发布消息</param>
        /// <param name="qos">QOS</param>
        /// <returns></returns>
        Task<bool> Publish(string topic, string message, QOSEnum qos = QOSEnum.ExactlyOnce);
        /// <summary>
        /// 发布字符串消息
        /// </summary>
        /// <typeparam name="T">返回对象</typeparam>
        /// <param name="topic">发布主题</param>
        /// <param name="message">发布消息</param>
        /// <param name="subTopic">返回主题，为空时不返回</param>
        /// <param name="pushqos">发布QOS</param>
        /// <param name="subqos">返回QOS</param>
        /// <returns></returns>
        Task<T> Publish<T>(string topic, string message,string subTopic, QOSEnum pushqos = QOSEnum.ExactlyOnce, QOSEnum subqos = QOSEnum.ExactlyOnce);
        /// <summary>
        /// 发布二进制流
        /// </summary>
        /// <param name="topic">发布主题</param>
        /// <param name="message">发布消息</param>
        /// <param name="qos">QOS</param>
        /// <returns></returns>
        Task<bool> PublishBinary(string topic, IEnumerable<byte> message, QOSEnum qos = QOSEnum.ExactlyOnce);
        /// <summary>
        /// 监听主题
        /// </summary>
        /// <param name="topic">监听主题</param>
        /// <param name="qos">监听OQS</param>
        /// <returns></returns>
        Task Subscribe(string topic, QOSEnum qos = QOSEnum.ExactlyOnce);
        /// <summary>
        /// 监听主题
        /// 设置主题对应的函数
        /// </summary>
        /// <param name="topic">监听主题</param>
        /// <param name="method">接收主题的函数名</param>
        /// <param name="type">接收函数的类Type</param>
        /// <param name="qos">接收主题的QOS</param>
        /// <returns></returns>
        Task Subscribe(string topic, string method, Type type, QOSEnum qos = QOSEnum.ExactlyOnce);
        /// <summary>
        /// 取消监听主题
        /// </summary>
        /// <param name="topic">要取消监听的主题</param>
        /// <returns></returns>
        Task UnSubscribe(string topic);
    }
}
